package com.googlecode.agscrum.controller.jsf.bean;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.faces.model.SelectItem;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.richfaces.component.Dropzone;
import org.richfaces.event.DropEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.googlecode.agscrum.model.entity.Item;
import com.googlecode.agscrum.model.entity.Product;
import com.googlecode.agscrum.model.entity.Sprint;
import com.googlecode.agscrum.model.entity.Status;
import com.googlecode.agscrum.model.entity.Task;
import com.googlecode.agscrum.model.exceptions.GScrumDomainException;
import com.googlecode.agscrum.model.service.Service;
import com.googlecode.agscrum.model.util.Criteria;

@Controller("scrumBoardControllerBean")
@Scope("request")
public class ScrumBoardControllerBean {

	private Product selectProduct;

	private Sprint selectSprint;

	private Product produto;

	@Autowired
	@Qualifier(value = "productService")
	private Service<Product, Long> productService;

	@Autowired
	@Qualifier(value = "statusService")
	private Service<Status, Long> statusService;

	@Autowired
	@Qualifier(value = "sprintService")
	private Service<Sprint, Long> sprintService;

	public Product getSelectProduct() {
		return selectProduct;
	}

	public void setSelectProduct(Product selectProduct) {
		this.selectProduct = selectProduct;
	}

	public Sprint getSelectSprint() {
		return selectSprint;
	}

	public void setSelectSprint(Sprint selectSprint) {
		if (selectSprint != null) {
			selectSprint = sprintService.findById(selectSprint.getId());
		}
		this.selectSprint = selectSprint;
	}

	public List<SelectItem> getProdutos() {
		Criteria criteria = Criteria.getInstance("Product.searchQuery",
				Product.class);
		criteria.setCacheable(true);
		List<Product> produtos = productService.readByCriteria(criteria);
		List<SelectItem> itemsProdutos = new ArrayList<SelectItem>();
		for (Product produto : produtos) {
			itemsProdutos.add(new SelectItem(produto, produto.getName()));
		}
		return itemsProdutos;
	}

	public List<SelectItem> getSprint() {
		List<SelectItem> itemsSprint = new ArrayList<SelectItem>();
		if (getSelectProduct() != null) {
			produto = productService.findById(selectProduct.getId());
			List<Sprint> listSprint = produto.getSprints();

			for (Sprint sprint : listSprint) {
				itemsSprint
						.add(new SelectItem(sprint, sprint.getDescription()));
			}
		}
		return itemsSprint;
	}

	private List<Status> allStatus;

	public List<Status> getAllStatus() {
		if (allStatus == null) {
			allStatus = statusService.readByCriteria(Criteria.getInstance(
					"Status.searchQuery", Status.class).setCacheable(true));
			Collections.sort(allStatus);
		}
		return allStatus;
	}

	public void processDrop(DropEvent dropEvent) {
		Dropzone dropzone = (Dropzone) dropEvent.getComponent();
		for (Item item : selectSprint.getItems()) {
			if (dropzone.getDropValue() instanceof Status) {
				if (item.changeStatusTask(item,
						(Task) dropEvent.getDragValue(), (Status) dropzone
								.getDropValue())) {
					try {
						sprintService.save(selectSprint);
					} catch (GScrumDomainException e) {
						e.printStackTrace();
					}
					return;
				}

			}
		}

	}

	public void createBurnDownChart(Graphics2D g2d, Object data) {
		CategoryDataset categorydataset = createDataset();
		JFreeChart jfreechart = ChartFactory.createLineChart("Burn Down Chart",
				"Dias", "Story Points/Itens", categorydataset,
				PlotOrientation.VERTICAL, false, true, false);
		jfreechart.setBackgroundPaint(Color.white);
		CategoryPlot categoryplot = (CategoryPlot) jfreechart.getPlot();
		categoryplot.setBackgroundPaint(Color.lightGray);
		categoryplot.setRangeGridlinePaint(Color.white);
		NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis();
		numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		LineAndShapeRenderer lineandshaperenderer = (LineAndShapeRenderer) categoryplot
				.getRenderer();
		lineandshaperenderer.setDrawOutlines(true);
		lineandshaperenderer.setUseFillPaint(true);
		BufferedImage bufferedImage = jfreechart.createBufferedImage(800, 250);
		g2d.drawImage(bufferedImage, 0, 0, null);
	}

	private CategoryDataset createDataset() {
		DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset();
		defaultcategorydataset.addValue(30D, "Items", "16/11/2008");
		defaultcategorydataset.addValue(25D, "Items", "17/11/2008");
		defaultcategorydataset.addValue(20D, "Items", "18/11/2008");
		defaultcategorydataset.addValue(15D, "Items", "19/11/2008");
		defaultcategorydataset.addValue(10D, "Items", "20/11/2008");
		defaultcategorydataset.addValue(5D, "Items", "21/11/2008");
		defaultcategorydataset.addValue(0D, "Items", "22/11/2008");
		return defaultcategorydataset;
	}
}
